package edu.bath.sensorframework.triplestore.agent;

import java.io.ByteArrayInputStream;

import org.jivesoftware.smack.XMPPException;
//import org.mortbay.jetty.Server;
//import org.mortbay.jetty.webapp.WebAppContext;
//import org.mortbay.thread.QueuedThreadPool;
import org.openrdf.repository.RepositoryException;
import org.openrdf.rio.RDFFormat;

import com.franz.agraph.repository.AGCatalog;
import com.franz.agraph.repository.AGRepository;
import com.franz.agraph.repository.AGRepositoryConnection;
import com.franz.agraph.repository.AGServer;

import edu.bath.sensorframework.client.ReadingHandler;
import edu.bath.sensorframework.client.SensorClient;

public class TripleStoreAgent {
	private boolean alive = true;
	private SensorClient sensorClient;
	
	private String agServerURL, agUsername, agPassword, agCatID, agRepoID;
	
	private AGServer server;
	private AGCatalog catalogue;
	private AGRepository repository;
	private AGRepositoryConnection conn;
	
	public static void main(String[] args) throws Exception {
		TripleStoreAgent tsa = new TripleStoreAgent("laptop", "laptop", "datastore", "bobbo", "smartHouse", "datastore@laptop");
		tsa.run();
	}
	
	private String nodeName;// TODO: Remove this, it is just a debugging option
	public TripleStoreAgent(String serverAddress, String serverName, String id, String password, String nodeName, String myJID) throws XMPPException {
		sensorClient = new SensorClient(serverAddress, serverName, id, password, myJID);
		this.nodeName = nodeName;
	}

	public void run() {
		// TODO: Load allgeograph server settings from config file
		agServerURL = "http://localhost:10035";
		agUsername = "root";
		agPassword = "bobbo";
		agCatID = "java-catalog";
		agRepoID = "SensorData";
		server = new AGServer(agServerURL, agUsername, agPassword);
		catalogue = server.getCatalog(agCatID);
		try {
			repository = catalogue.createRepository(agRepoID);
			repository.initialize();
			conn = repository.getConnection();
		} catch (RepositoryException e1) {
			e1.printStackTrace();
		}
		
		try {
			sensorClient.subscribe(nodeName);
		} catch (XMPPException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
//		Server server = new Server(18080);
//		WebAppContext handler = new WebAppContext();
//		handler.setContextPath("/");
//		handler.setWar("/home/adan/Desktop/app.war");
//        server.setHandler(handler);
//
//        // Other misc. options
//        QueuedThreadPool pool = new QueuedThreadPool();
//        pool.setMaxThreads(20);
//        server.setThreadPool(pool);
//
//        // And start it up
//        try {
//			server.start();
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
        ///server.join(); /// NOTE: I'm assuming that this will just sit and wait for the threads to terminate, but I don't need that
		
		sensorClient.addHandler(nodeName, new ReadingHandler() {
			@Override
			public void handleIncomingReading(String rdf) {
				try{
				conn.add(new ByteArrayInputStream(rdf.getBytes()), "", RDFFormat.RDFXML);
				}catch(Exception e) {}
			}
		});
		
		while(alive) {
        	// Wait for 5s until more data can have come in
        	try {
				Thread.sleep(5000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
        }
	}

	// TODO: Could all of these static methods be rolled into a single "getAgentGateway" method, 
	// which returns an object which was initialised previously in the agent to interact with GWT?
	public static String getAgraphUsername() {
		return "root";
	}
	
	public static String getAgraphServerURL() {
		return "blah";
	}
	
	public static String getAgraphCatID() {
		return "cat1";
	}
	
	public static String getAgraphRepoID() {
		return "repo1";
	}
	
	public static boolean hasAgraphPassword() {
		return true;
	}
	
	// TODO: Make this encrypted somehow?
	public static void setAgraphPassword(String password) {
		
	}
	
	public static void setAgraphRepoID(String repoID) {
		
	}
	
	public static void setAgraphCatID(String catID) {
		
	}
	
	public static void setAgraphUsername(String username) {
		
	}
	
	public static void setAgraphServerURL(String serverURL) {
		
	}

	public static void addDataSource(String handle) throws RuntimeException {
		throw new RuntimeException("This is a test exception!");
	}
}
